package com.example.nio.groupchat;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;

public class GroupChatServer {

    private Selector selector = null;
    private ServerSocketChannel serverSocketChannel = null;
    private static final int PORT = 6667;

    public GroupChatServer(){
        try {
            // 启用selector
            selector = Selector.open();
            // 启用服务端channel
            serverSocketChannel = ServerSocketChannel.open();
            InetSocketAddress inetSocketAddress = new InetSocketAddress(PORT);
            // 绑定端口
            serverSocketChannel.socket().bind(inetSocketAddress);
            serverSocketChannel.configureBlocking(false);
            serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void listen(){
        try {
            while (true){
                int select = selector.select(3000);
                if (select > 0){
                    Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
                    while (iterator.hasNext()){
                        SelectionKey selectionKey = iterator.next();
                        if (selectionKey.isAcceptable()){
                            // 客户端通道注册到selector
                            SocketChannel socketChannel = serverSocketChannel.accept();
                            socketChannel.register(selector, SelectionKey.OP_READ);
                            socketChannel.configureBlocking(false);
                            System.out.println(socketChannel.getRemoteAddress() + " 上线了");
                        }

                        if (selectionKey.isReadable()){
                            readData(selectionKey);
                        }
                        // 事件处理完移除迭代器
                        iterator.remove();
                    }
                } else {
                    System.out.println("服务器等待连接中...");
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }
    }

    // 读取消息
    public void readData(SelectionKey selectionKey){
        SocketChannel channel = null;
        try {
            channel = (SocketChannel) selectionKey.channel();
            ByteBuffer attachment = (ByteBuffer) selectionKey.attachment();
            channel.configureBlocking(false);
            int read = channel.read(attachment);
            // 说明读取到数据了
            if (read > 0){
                String msg = new String(attachment.array());
                // 服务端输出信息
                System.out.println("from 客户端:" + msg);
                // 向其他客户端转发
                sendToOtherClients(msg, channel);
            }
        } catch (IOException e) {
            try {
                System.out.println(channel.getRemoteAddress() + " 下线了");
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
    }

    //转发消息给其他用户，但是要记得排除自己
    public void sendToOtherClients(String msg, SocketChannel selfChannel){
        System.out.println("服务器转发消息中...");
        try {
            for (SelectionKey key : selector.keys()){
                SocketChannel channel = (SocketChannel) key.channel();
                if (channel != selfChannel){
                    ByteBuffer byteBuffer = ByteBuffer.wrap(msg.getBytes());
                    channel.write(byteBuffer);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
